package com.ruoyi.common.utils;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Enumeration;
/**
 * TYF   
 * ZIP   压缩  解压
 */
public class ZipUtil {

    public static Logger logger = LoggerFactory.getLogger(ZipUtil.class);

    public static final int BUFFER = 2048;


    public static boolean doZip(String fileName, String filePath) {
        boolean flag = false;
        BufferedInputStream origin = null;
        try {
            FileOutputStream dest = new FileOutputStream(fileName);
            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
            byte[] data = new byte[2048];
            File f = new File(filePath);
            File[] files = f.listFiles();
            for (int i = 0; i < files.length; i++) {
                FileInputStream fi = new FileInputStream(files[i]);
                origin = new BufferedInputStream(fi, 2048);
                ZipEntry entry = new ZipEntry(files[i].getName());
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, 2048)) != -1) {
                    out.write(data, 0, count);
                }
                origin.close();
            }
            out.close();
            flag = true;
        } catch (Exception e) {
            flag = false;
            logger.error(e+"");
        }
        return flag;
    }

    public static boolean doZipCode(String fileName, String filePath, String chartcode) {
        boolean flag = false;
        File inputFile = null;
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(fileName));
            out.setEncoding(chartcode);
            inputFile = new File(filePath);
            doZipByOpache(out, inputFile, null, false);
            flag = true;
        } catch (FileNotFoundException e) {
            logger.error(e+"");
            flag = false;
        } catch (Exception e) {
            logger.error(e+"");
            flag = false;
        } finally {
            try {
                out.close();
                inputFile = null;
            } catch (IOException e) {
                logger.error(e+"");
            }
        }
        return flag;
    }


    public static boolean doZip(String fileName, File[] files) {
        boolean flag = false;
        BufferedInputStream origin = null;
        try {
            FileOutputStream dest = new FileOutputStream(fileName);
            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
            byte[] data = new byte[2048];
            ZipEntry entry = null;
            FileInputStream fi = null;
            for (int i = 0; i < files.length; i++) {
                fi = new FileInputStream(files[i]);
                origin = new BufferedInputStream(fi, 2048);
                entry = new ZipEntry(files[i].getName());
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, 2048)) != -1) {
                    out.write(data, 0, count);
                }
                origin.close();
            }
            out.close();
            flag = true;
        } catch (Exception e) {
            flag = false;
            logger.error(e+"");
        }
        return flag;
    }


    public static boolean doZipCode(String fileName, File[] files, String chartcode) {
        boolean flag = false;
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(fileName));
            out.setEncoding(chartcode);
            for (int i = 0; i < files.length; i++) {
                doZipByOpache(out, files[i], files[i].getName());
            }
            flag = true;
        } catch (FileNotFoundException e) {
            logger.error(e+"");
            flag = false;
        } catch (Exception e) {
            logger.error(e+"");
            flag = false;
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                logger.error(e+"");
            }
        }
        return flag;
    }


    public static void doZipByOpache(ZipOutputStream out, File f, String base) throws Exception {
        doZipByOpache(out, f, base, false);
    }


    public static void doZipByOpache(ZipOutputStream out, File f, boolean first) throws Exception {
        doZipByOpache(out, f, null, true);
    }


    private static void doZipByOpache(ZipOutputStream out, File f, String base, boolean first) throws Exception {
        if (first) {
            if (f.isDirectory()) {
                out.putNextEntry(new ZipEntry(File.separator));
                base = base + f.getName();
                first = false;
            } else {
                base = f.getName();
            }
        }
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            base = (base != null) ? (base + File.separator) : "";
            for (int i = 0; i < fl.length; i++) {
                doZipByOpache(out, fl[i], base + fl[i].getName(), first);
            }
        } else {
            out.putNextEntry(new ZipEntry(base));
            FileInputStream in = new FileInputStream(f);
            int b;
            while ((b = in.read()) != -1) {
                out.write(b);
            }
            in.close();
        }
    }


    public static boolean unZip(String fileName) {
        return unZip(fileName, (fileName != null) ? fileName.substring(0, fileName.lastIndexOf(".")) : null);
    }


    public static boolean unZipCode(String fileName, String chartcode) {
        return unZipCode(fileName, (fileName != null) ? fileName.substring(0, fileName.lastIndexOf(".")) : null, chartcode);
    }


    public static boolean unZip(String fileName, String filePath) {
        boolean flag = false;
        ZipFile zipFile = null;
        try {
            String ename = null;
            zipFile = new ZipFile(fileName);
            Enumeration<? extends ZipEntry> emu = zipFile.getEntries();
            while (emu.hasMoreElements()) {
                ZipEntry entry = emu.nextElement();
                ename = entry.getName();

                if (entry.isDirectory()) {
                    (new File(filePath + File.separator + ename)).mkdirs();
                    continue;
                }
                BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
                File file = new File(filePath + File.separator + ename);


                File parent = file.getParentFile();
                if (parent != null && !parent.exists()) {
                    parent.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(fos, 2048);
                int count = 0;
                byte[] data = new byte[2048];
                while ((count = bis.read(data, 0, 2048)) != -1) {
                    bos.write(data, 0, count);
                }
                bos.flush();
                bos.close();
                bis.close();
            }
            flag = true;
        } catch (IOException e) {
            logger.error(e+"");
            flag = false;
        } finally {
            try {
                if (zipFile != null) {
                    zipFile.close();
                }
            } catch (IOException e) {
                logger.error(e+"");
            }
        }
        return flag;
    }


    public static boolean unZipCode(String fileName, String filePath, String chartcode) {
        boolean flag = false;
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(fileName, chartcode);
            unZipFileByOpache(zipFile, filePath);
            flag = true;
        } catch (IOException e) {
            logger.error(e+"");
            flag = false;
        } catch (Exception e) {
            logger.error(e+"");
            flag = false;
        } finally {
            try {
                if (zipFile != null) zipFile.close();
            } catch (IOException e) {
                logger.error(e+"");
            }
            zipFile = null;
        }
        return flag;
    }


    private static void unZipFileByOpache(ZipFile zipFile, String unZipRoot) throws Exception, IOException {
        Enumeration<ZipEntry> e = zipFile.getEntries();

        while (e.hasMoreElements()) {
            ZipEntry zipEntry = e.nextElement();
            InputStream fis = zipFile.getInputStream(zipEntry);
            if (zipEntry.isDirectory()) {
                continue;
            }
            File file = new File(unZipRoot + File.separator + zipEntry.getName());
            File parentFile = file.getParentFile();
            parentFile.mkdirs();
            FileOutputStream fos = new FileOutputStream(file);
            byte[] b = new byte[1024];
            int len;
            while ((len = fis.read(b, 0, b.length)) != -1) {
                fos.write(b, 0, len);
            }
            fos.close();
            fis.close();
            file = null;
        }
    }






    public static void main(String[] args) {
        File fileml = new File("E:\\home\\ruoyi\\logs\\");
        logger.debug(fileml+"");
        if (fileml.isDirectory()) {
            logger.debug("fileml.isDirectory():" + fileml.isDirectory() + "," + fileml.listFiles());
            doZipCode("E:\\tmp\\水科总院试点.zip", fileml.listFiles(), "GBK");
        }
    }
}
